﻿using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

namespace Hont.AStar
{
    public class Grid : IGrid, IEnumerable<Position>
    {
        Node[,,] mNodes;
        int mLenght;
        int mWidth;
        int mHeight;

        public int Lenght { get { return mLenght; } }
        public int Width { get { return mWidth; } }
        public int Height { get { return mHeight; } }

        Node IGrid.this[int x, int y, int z] { get { return mNodes[x, y, z]; } }


        public Grid(int lenght, int width, int height)
        {
            this.mLenght = lenght;
            this.mWidth = width;
            this.mHeight = height;
            mNodes = new Node[mLenght, mHeight, mWidth];

            int id = 0;
            for (int i = 0; i < mLenght; i++)
            {
                for (int j = 0; j < mHeight; j++)
                {
                    for (int k = 0; k < mWidth; k++)
                    {
                        mNodes[i, j, k] = new Node(i, j, k, id);
                        mNodes[i, j, k].Init(0, 0, true, 1);
                        id++;
                    }
                }
            }
        }

        public void Clear()
        {
            for (int i = 0; i < mLenght; i++)
            {
                for (int j = 0; j < mHeight; j++)
                {
                    for (int k = 0; k < mWidth; k++)
                    {
                        mNodes[i, j, k].Init(0, 0, true, 1);
                    }
                }
            }
        }

        public void SetUserData(Position pos, object userData)
        {
            mNodes[pos.X, pos.Y, pos.Z].UserData = userData;
        }

        public object GetUserData(Position pos)
        {
            return mNodes[pos.X, pos.Y, pos.Z].UserData;
        }

        public void SetCost(Position pos, int cost = 14)
        {
            mNodes[pos.X, pos.Y, pos.Z].Cost = cost;
        }

        public int GetCost(Position pos)
        {
            return mNodes[pos.X, pos.Y, pos.Z].Cost;
        }

        public int GetF(Position pos)
        {
            return mNodes[pos.X, pos.Y, pos.Z].F;
        }

        public int GetG(Position pos)
        {
            return mNodes[pos.X, pos.Y, pos.Z].G;
        }

        public int GetH(Position pos)
        {
            return mNodes[pos.X, pos.Y, pos.Z].H;
        }

        public void SetMask(Position pos, int mask)
        {
            mNodes[pos.X, pos.Y, pos.Z].Mask = mask;
        }

        public int GetMask(Position pos)
        {
            return mNodes[pos.X, pos.Y, pos.Z].Mask;
        }

        public void SetIsWalkable(Position pos, bool isWalkable = false)
        {
            mNodes[pos.X, pos.Y, pos.Z].Walkable = isWalkable;
        }

        public bool GetIsWalkable(Position pos)
        {
            return mNodes[pos.X, pos.Y, pos.Z].Walkable;
        }

        IEnumerator<Position> IEnumerable<Position>.GetEnumerator()
        {
            foreach (var item in mNodes)
            {
                yield return item.Position;
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            foreach (var item in mNodes)
            {
                yield return item.Position;
            }
        }
    }
}
